package bootLoader;

import components.Util;
import components.exceptions.IntToBinaryException;
import components.exceptions.UnexpectedNotifyReceivedException;
import components.memory.Memory;
import components.register.RegisterGroup;
import controller.MemoryController;
import controller.notify.Notify;
import controller.notify.NotifyBus;

/**
 * 
 * This is a fake loader, initialize the content in memory as follows:
 * 
 * R1 = 1000
 * 
 * R2 = 100
 * 
 * STR 0, 0, 50 //put content of R1 into memory location 50
 * 
 * LDX 0, 50 //load content in memory location 50 into X0
 * 
 * STR 1, 1, 0 //store the value in R2 into memory location c(X0)+0
 * 
 * LDR 0, 1, 0 //load the value in memory location c(X0)+0 into R1
 * 
 * IAR 0, 1 //Immediate add 1 into R1
 * 
 * OUT 0, 1 //Output the value of R0 to device 1(console printer)
 * 
 * IAR 0, 1 //Immediate add 1 into R1
 * 
 * OUT 0, 1 //Output the value of R0 to device 1
 * 
 * IAR 0, 1 //Immediate add 1 into R1
 * 
 * OUT 0, 1 //Output the value of R0 to device 1
 * 
 * IAR 0, 1 //Immediate add 1 into R1
 * 
 * OUT 0, 1 //Output the value of R0 to device 1
 * 
 * IAR 0, 1 //Immediate add 1 into R1
 * 
 * ...
 * 
 * The instruction segment starts at address 4000, data segment starts at
 * address 1000.
 * 
 * @author Chz
 * 
 */
public class FakeLoader {

	RegisterGroup regs = RegisterGroup.getInstance();
	Memory mm = Memory.getInstance();
	NotifyBus bus = NotifyBus.getInstance();

	public FakeLoader() {

	}

	public void init() throws IntToBinaryException {
		// R0 = 1000
		regs.setGPR(Util.intToBinary(1000, RegisterGroup.GPR_LEN), 0);

		// R1 = 100
		regs.setGPR(Util.intToBinary(250, RegisterGroup.GPR_LEN), 1);

		// 4000: STR 0, 0, 50 //put content of R0(1000) into memory location 50
		mm.setContent(4000, new int[] { 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0,
				0, 1, 0 });

		// 4001: LDX 0, 50 //load content in memory location 50(1000) into X0
		mm.setContent(4001, new int[] { 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0,
				0, 1, 0 });

		// 4002: STR 1, 1, 0 //store the value in R1(100) into memory location
		// c(X0)+0
		mm.setContent(4002, new int[] { 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 0,
				0, 0, 0 });

		// 4003: LDR 0, 1, 0 //load the value in memory location c(X0)+0 into R0
		mm.setContent(4003, new int[] { 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0,
				0, 0, 0 });

		for (int i = 0; i < 100; i+=2) {
			// 4004: IAR 0, 1 //Immediate add 1 into R0
			mm.setContent(4004 + i, new int[] { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0,
					0, 0, 0, 0, 0, 1 });

			// 4105: OUT 0, 1 //Output the value of R0 to device 1(console
			// printer)
			mm.setContent(4004 + i + 1, new int[] { 1, 1, 1, 1, 1, 0, 0, 0, 0,
					0, 0, 0, 0, 0, 0, 1 });
		}

	}

	/***
	 * 
	 public void init() throws IntToBinaryException { // R1 = 1000
	 * regs.setGPR(Util.intToBinary(1000, RegisterGroup.GPR_LEN), 1);
	 * 
	 * // R0 = 250 regs.setGPR(Util.intToBinary(250, RegisterGroup.GPR_LEN), 0);
	 * 
	 * // 4000: STR 1, 0, 50 //put content of R1(1000) into memory location 50
	 * mm.setContent(4000, new int[] { 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0,
	 * 1, 0 });
	 * 
	 * // 4001: LDX 0, 50 //load content in memory location 50(1000) into X0
	 * mm.setContent(4001, new int[] { 1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0,
	 * 1, 0 });
	 * 
	 * for (int i = 0; i < 20; i += 2) { // 4004: IAR 0, 1 //Immediate add 1
	 * into R0 mm.setContent(4002 + i, new int[] { 0, 0, 0, 1, 1, 0, 0, 0, 0, 0,
	 * 0, 0, 0, 0, 0, 1 });
	 * 
	 * // 4105: OUT 0, 1 //Output the value of R0 to device 1(console //
	 * printer) mm.setContent(4002 + i + 1, new int[] { 1, 1, 1, 1, 1, 0, 0, 0,
	 * 0, 0, 0, 0, 0, 0, 0, 1 }); }
	 * 
	 * }
	 */

	public void start() throws IntToBinaryException {
		regs.setPC(Util.intToBinary(4000, RegisterGroup.PC_LEN));
		bus.sendNotify(new Notify(Notify.FETCH), MemoryController.getInstance());
		// TODO Auto-generated catch block

	}
}
